home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 286_01 / arc2.c < prev    next >
Text File  |  1989-05-23  |  5KB  |  118 lines

  1. #include <stdio.h>
  2. #include <gds.h>
  3.  
  4. extern int ARCSTTX, ARCSTTY, ARCENDX, ARCENDY, ARCSTTR, ARCENDR;
  5.  
  6. struct cpoint {
  7.     int point,state,region;
  8. };
  9.  
  10. extern int arcreg[], regbit[];
  11.  
  12. #define on 1
  13. #define off 0
  14.  
  15. /*==============================================================*
  16.  *  Arc2 use a special way to calculate the starting and ending *
  17.  *    coordiantes of the arc. It is quite difficult for me to   *
  18.  *    explain with my limited English vocabulary. But generally *
  19.  *    speaking, the method used can be summarized as follows:   *
  20.  *    a. A circle is divided into 8 symmetrical portion. When   *
  21.  *       the circle is drawn, only one of the 8 portion is      *
  22.  *       calculated. Others portions are drawn using the same   *
  23.  *       result but appropiate adjustment is given.             *
  24.  *    b. So when we calculate the starting and ending points,   *
  25.  *       we do not calculate the actual coordinates instead     *
  26.  *       we calcalate the correspond coordinates in the portion *
  27.  *       that we actually calculate and draw.                   *
  28.  *    c. Actually it is not correct to say `coordinates' above  *
  29.  *       because I only find the x coordiate only.              *
  30.  *    d. Since a circle is symmetrical about its center, I      *
  31.  *       can rotate it without affecting the output. So         *
  32.  *       I always rotate (logically) the circle such that       *
  33.  *       the starting point is always within 45 degree          *
  34.  *       in clockwise direction from the vertical upward line   *
  35.  *    e. After calculation, I rotate it back to originally      *
  36.  *       position.                                              *
  37.  *    f. There are some special cases handling which make       *
  38.  *       the program even more difficult to understand.         *
  39.  *       Therefore, unless you are absolutely necessary         *
  40.  *       to change this program, better left it alone.          *
  41.  *                                                              *
  42.  *==============================================================*/
  43.  
  44. Arc2(centerx,centery,radius,deg1,deg2)
  45. int centerx,centery,radius,deg1,deg2;
  46. {
  47.     int region2, arcp, rotreg;
  48.     struct cpoint pnt1, pnt2;
  49.  
  50.     if (deg2<=0) {        /* deg2 must be greater than 0 */
  51. setnull:
  52.         LASTX=centerx;
  53.         LASTY=centery;
  54.         ARCSTTX=ARCSTTY=ARCENDX=ARCENDY=0;
  55.         return;
  56.     }
  57.  
  58.     /* if deg2 >= 360, use Arc1 */
  59.     if (deg2>=360) Arc1(centerx,centery,radius,0xff);
  60.  
  61.     centerx += ORGX;   /* get absolute location */
  62.     centery += ORGY;
  63.  
  64.     /* if the whole circle is outside is outside the window, return */
  65.     if ((centerx+radius < WINX1) || (centerx-radius > WINX2) ||
  66.         (centery+radius < WINY1) || (centery-radius > WINY2)) goto setnull;
  67.     setcptr(1);  /* always use '1' in arc drawing */
  68.  
  69.     /* deg1=deg1 mod 360, result always is positive */
  70.     arcp=deg1/360;
  71.     deg1-=arcp*360;
  72.     if (deg1<0) deg1+=360;
  73.  
  74.     rotreg=deg1/45;     /* 45 degree a region, get region number */
  75.     deg1 %= 45;         /* get angle within the region */
  76.  
  77.     deg2 += deg1;       /* find the ending degree */
  78.     region2=deg2/45;    /* calculate the region number */
  79.     deg2 %= 45;         /* and angle within the region */
  80.  
  81.     arcp= 0xff ^ arcreg[region2];       /* find region needed to be filled */
  82.     arcp=arcp<<rotreg;  /* rotate lower 8 bit or arcp */
  83.     arcp=(arcp & 0xff) | ((arcp & 0xff00) >> 8);
  84.     region2=(region2+rotreg) & 0x07; /* get actual region number after 
  85.                                          unrotate */
  86.     ARCSTTR=rotreg;  /* for finding the actual coordinate of */
  87.     ARCENDR=region2; /* starting and ending point */
  88.  
  89.     /* calculate the corresponding x coordinate for 
  90.        starting and ending point and stored in struct pnt1 and pnt2 */
  91.     setpnt(&pnt1,&pnt1,rotreg,on,off,radius,radius,45-deg1,deg1);
  92.     setpnt(&pnt2,&pnt2,region2,off,on,radius,radius,45-deg2,deg2);
  93.     if (pnt1.point==0) {
  94.         ARCSTTX=0;
  95.         ARCSTTY=radius;
  96.     }
  97.     if (pnt2.point==0) {
  98.         ARCENDX=0;
  99.         ARCENDY=radius;
  100.     }
  101.     /* special cases handling !! */
  102.     adjpnt(&arcp,&pnt1,&pnt2,(deg1<deg2),rotreg);
  103.     ARCSPEC=arcp;
  104.     circ(centerx,centery,radius,STYLE,&pnt1,&pnt2);
  105.     /* another special case handling !! */
  106.     if (pnt1.point >= 0) {
  107.         ARCSTTX=LASTX;
  108.         ARCSTTY=LASTY;
  109.     }
  110.     if (pnt2.point >= 0) {
  111.         ARCENDX=LASTX;
  112.         ARCENDY=LASTY;
  113.     }
  114.     LASTX=centerx;
  115.     LASTY=centery;
  116. }
  117.  
  118.